#include <iostream>
#include <pthread.h>
#include <unistd.h>

using namespace std;

// 互斥锁和条件变量都定义为自动初始化和释放
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

const int num = 5; // 创建五个线程

void* Active(void* args)
{
    const char* name = static_cast<const char*>(args);

    while(true)
    {
        // 加锁
        pthread_mutex_lock(&mtx);

        // 等待条件满足
        pthread_cond_wait(&cond, &mtx);
        cout << "\t线程 " << name << " 正在运行" << endl;

        // 解锁
        pthread_mutex_unlock(&mtx);
    }

    return nullptr;
}

int main()
{
    pthread_t pt[num];
    for(int i = 0; i < num; i++)
    {
        char* name = new char[32];
        snprintf(name, 32, "thread-%d", i);
        pthread_create(pt + i, nullptr, Active, name);
    }

    // 等待所有次线程就位
    sleep(3);

    // 主线程唤醒次线程
    while(true)
    {
        cout << "Main thread wake up Other thread!" << endl;
        // pthread_cond_signal(&cond); // 单个唤醒
        pthread_cond_broadcast(&cond); // 广播
        sleep(1);
    }

    for(int i = 0; i < num; i++)
        pthread_join(pt[i], nullptr);

    return 0;
}

// // 全局互斥锁，无需手动初始化和销毁
// pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;

// void* threadRoutine(void* args)
// {
//     cout << "我是次线程，我开始运行了" << endl;

//     // 申请锁
//     pthread_mutex_lock(&mtx);
//     cout << "我是次线程，我申请到了一把锁" << endl;

//     // 在不释放锁的情况下，再次申请锁，陷入 死锁 状态
//     pthread_mutex_lock(&mtx);
//     cout << "我是次线程，我又再次申请到了一把锁" << endl;

//     pthread_mutex_unlock(&mtx);

//     return nullptr;
// }

// int main()
// {
//     pthread_t t;
//     pthread_create(&t, nullptr, threadRoutine, nullptr);

//     // 等待次线程先跑
//     sleep(3);

//     // 主线程帮忙释放锁
//     pthread_mutex_unlock(&mtx);
//     cout << "我是主线程，我已经帮次线程释放了一把锁" << endl;

//     // 等待次线程后续动作
//     sleep(3);

//     pthread_join(t, nullptr);
//     cout << "线程等待成功" << endl;
//     return 0;
// }

// #include <iostream>
// #include <unistd.h>
// #include "Thread.hpp"
// #include "LockGuard.hpp"
// using namespace std;

// // 创建一把全局锁
// pthread_mutex_t mtx;
// int tickets = 1000; // 有 1000 张票

// // 自己封装的线程库返回值为 void
// void threadRoutine(void *args)
// {
//     int sum = 0;
//     const char* name = static_cast<const char*>(args);
//     while (true)
//     {
//         // 进入临界区，加锁
//         {
//             // 自动加锁、解锁
//             LockGuard guard(&mtx);

//             // 如果票数 > 0 才能抢
//             if (tickets > 0)
//             {
//                 usleep(2000); // 耗时 2ms
//                 sum++;
//                 tickets--;
//             }
//             else
//                 break; // 没有票了
//         }

//         // 抢到票后还有后续动作
//         usleep(2000); // 抢到票后也需要时间处理
//     }

//     // 屏幕也是共享资源，加锁可以有效防止打印结果错行
//     {
//         LockGuard guard(&mtx);
//         cout << "线程 " << name << " 抢票完毕，最终抢到的票数 " << sum << endl;
//     }
// }

// int main()
// {
//     // 在线程创建前，初始化互斥锁
//     pthread_mutex_init(&mtx, nullptr);

//     // 创建一批线程
//     Thread t1(1, threadRoutine, (void*)"thread-1");
//     Thread t2(2, threadRoutine, (void*)"thread-2");
//     Thread t3(3, threadRoutine, (void*)"thread-3");

//     // 启动
//     t1.run();
//     t2.run();
//     t3.run();

//     // 等待
//     t1.join();
//     t2.join();
//     t3.join();

//     // 线程退出后，销毁互斥锁
//     pthread_mutex_destroy(&mtx);

//     cout << "剩余票数: " << tickets << endl;

//     return 0;
// }

// void threadRoutine(void* args)
// {}

// int main()
// {
//     Thread t1(1, threadRoutine, nullptr);
//     cout << "thread ID: " << t1.getTID() << ", thread name: " << t1.getName() << ", thread status: " << (int)t1.getStatus() << endl;
//     t1.run();
//     cout << "thread ID: " << t1.getTID() << ", thread name: " << t1.getName() << ", thread status: " << (int)t1.getStatus() << endl;
//     t1.join();
//     cout << "thread ID: " << t1.getTID() << ", thread name: " << t1.getName() << ", thread status: " << (int)t1.getStatus() << endl;

//     return 0;
// }

// int tickets = 1000; // 有 1000 张票

// // 需要定义在 threadRoutine 之前
// class TData
// {
// public:
//     TData(const string &name, pthread_mutex_t* pmtx)
//         :_name(name), _pmtx(pmtx)
//     {}

// public:
//     string _name;
//     pthread_mutex_t* _pmtx;
// };

// void* threadRoutine(void* args)
// {
//     int sum = 0;
//     TData* td = static_cast<TData*>(args);
//     while(true)
//     {
//         // 进入临界区，加锁
//         pthread_mutex_lock(td->_pmtx);

//         // 如果票数 > 0 才能抢
//         if(tickets > 0)
//         {
//             usleep(2000); // 耗时 2ms
//             sum++;
//             tickets--;

//             // 出临界区了，解锁
//             pthread_mutex_unlock(td->_pmtx);
//         }
//         else
//         {
//             // 如果判断没有票了，也应该解锁
//             pthread_mutex_unlock(td->_pmtx);
//             break; // 没有票了
//         }

//         // 抢到票后还有后续动作
//         usleep(2000); //抢到票后也需要时间处理
//     }

//     // 屏幕也是共享资源，加锁可以有效防止打印结果错行
//     pthread_mutex_lock(td->_pmtx);
//     cout << "线程 " << td->_name << " 抢票完毕，最终抢到的票数 " << sum << endl;
//     pthread_mutex_unlock(td->_pmtx);

//     delete td;
//     return nullptr;
// }

// int main()
// {
//     // 创建一把锁
//     pthread_mutex_t mtx;

//     // 在线程创建前，初始化互斥锁
//     pthread_mutex_init(&mtx, nullptr);

//     pthread_t pt[5];
//     for(int i = 0; i < 5; i++)
//     {
//         char* name = new char(16);
//         snprintf(name, 16, "thread-%d", i);
//         TData *td = new TData(name, &mtx);

//         pthread_create(pt + i, nullptr, threadRoutine, td);
//     }

//     for(int i = 0; i < 5; i++)
//         pthread_join(pt[i], nullptr);

//     cout << "所有线程均已退出，剩余票数: " << tickets << endl;

//     // 线程退出后，销毁互斥锁
//     pthread_mutex_destroy(&mtx);

//     return 0;
// }

// int main()
// {
//     pthread_mutex_t mtx; //定义互斥锁
//     pthread_mutex_init(&mtx, nullptr); // 初始化互斥锁

//     // 临界资源访问操作...

//     pthread_mutex_destroy(&mtx); // 销毁互斥锁
//     return 0;
// }

// int tickets = 1000; // 有 1000 张票

// void* threadRoutine(void* args)
// {
//     int sum = 0;
//     const char* name = static_cast<const char*>(args);
//     while(true)
//     {
//         // 如果票数 > 0 才能抢
//         if(tickets > 0)
//         {
//             usleep(2000); // 耗时 2ms
//             sum++;
//             tickets--;
//         }
//         else
//             break; // 没有票了

//         usleep(2000); //抢到票后也需要时间处理
//     }

//     cout << "线程 " << name << " 抢票完毕，最终抢到的票数 " << sum << endl;
//     delete name;
//     return nullptr;
// }

// int main()
// {
//     pthread_mutex_t mtx;
//     pthread_t pt[5];
//     for(int i = 0; i < 5; i++)
//     {
//         char* name = new char(16);
//         snprintf(name, 16, "thread-%d", i);
//         pthread_create(pt + i, nullptr, threadRoutine, name);
//     }

//     for(int i = 0; i < 5; i++)
//         pthread_join(pt[i], nullptr);

//     cout << "所有线程均已退出，剩余票数: " << tickets << endl;

//     return 0;
// }